package com.huanlis.workflow.server.engine;

import com.huanlis.core.Action;
import com.huanlis.core.ActionRegistry;
import com.huanlis.core.BaseDomain;
import com.huanlis.workflow.server.domain.FlowConfig;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.concurrent.ConcurrentHashMap;

public class AsyncWorkflowEngine {


    private final FlowRepository flowRepository = new FlowRepository();

    @SuppressWarnings("rawtypes")
    public void initialize(List<String> jarPaths, FlowConfig flowConfig) {

        List<Action<? extends BaseDomain, ? extends BaseDomain>> actions = new ArrayList<>();
        Map<String, Action<? extends BaseDomain, ? extends BaseDomain>> actionMap = new ConcurrentHashMap<>();
        // 1. 加载所有Action
        jarPaths.forEach(jar -> {
            ActionRegistry actionRegistry = new ActionRegistry();
            List<Action<? extends BaseDomain, ? extends BaseDomain>> actionList = new ArrayList<>();
            try {
                URL url = new URL("file:" + jar);
                URLClassLoader urlClassLoader = URLClassLoader.newInstance(new URL[]{url});
                ServiceLoader<Action> loader = ServiceLoader.load(Action.class, urlClassLoader);
                for (Action action : loader) {
                    System.out.println("加载插件jar中的动作 " + action.getClass().getName());
                    actionList.add((Action<? extends BaseDomain, ? extends BaseDomain>) action);
                    actionMap.put(action.getClass().getName(), (Action<? extends BaseDomain, ? extends BaseDomain>) action);
                }
            } catch (MalformedURLException e) {
                throw new RuntimeException(e);
            }
        });

        // 2. 注册所有流程
        flowRepository.registerFlow("", actions);
    }

    public String startFlow(String flowId, BaseDomain input) {
        // 3. 执行并返回执行ID
        return flowRepository.executeFlow(flowId, input);
    }
}
